#ifndef XL_UPLOADER_IMAGE_PREVIEW_CTRL_H
#define XL_UPLOADER_IMAGE_PREVIEW_CTRL_H
#include <atlstr.h>
#include <atltypes.h>
#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>
#include "../libuploader/libxluploader.h"
#include "xDocument.h"


typedef CWinTraits<
	WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
	0
	> CImagePreviewCtrlTraits;


class CImagePreviewCtrl
	: public CWindowImplBaseT<ATL::CWindow, CImagePreviewCtrlTraits>
	, public CxDocument::IObserver
{
private:
	ULONG_PTR                 gdiplusToken;
	CxDocument               *m_pDoc;
	tstring                   m_fileName;
	HBITMAP                   m_bitmap;
	tstring                   m_fileNameLoading;
	bool                      m_isLoadingFileRemoved;

	typedef std::map<
	                 tstring,
	                 HBITMAP,
	                 func_tstring_iless<tstring>
	                >         _Cache;
	_Cache                    m_cache;

	HANDLE                    m_semaphore;
	CRITICAL_SECTION          m_cs;
	HANDLE                    m_thread;
	bool                      m_exiting;
	static unsigned __stdcall _LoadImageThread(void *);
	void _Init();
	void _DeInit();

	void _AttachBitmap(const tstring &fileName, HBITMAP bitmap);
	void _RemoveBitmap(const tstring &fileName = _T(""));

	void _DrawText(HDC, TCHAR *, const CRect &);

public:
	DECLARE_WND_CLASS_EX(_T("xl::ImagePreviewCtrl"), 0, COLOR_3DFACE)
	typedef CWindowImplBaseT<ATL::CWindow, CImagePreviewCtrlTraits>	_Base;

	CImagePreviewCtrl(CxDocument *pDoc);
	~CImagePreviewCtrl(void);

	//////////////////////////////////////////////////////////////////////////
	// public methods
	HWND create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL);
	bool setFile(const tstring &fileName);
	// void clear();

	BEGIN_MSG_MAP(CImagePreviewCtrl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	//////////////////////////////////////////////////////////////////////////
	// virtual 
	virtual void onEvent(CxDocument::IObserver::EVT evt, void *param);
};

#endif